package com.ep.thirdPlatformProject.system.config.common;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Data
@Configuration
@EnableCaching
@RequiredArgsConstructor
@ConfigurationProperties(prefix = "caffeine")
public class CaffeineProperties {


    /**
     * 初始容量
     */
    private int initialCapacity;

    /**
     * 最大大小
     */
    private int maximumSize;

    /**
     * 写入分钟后过期
     */
    private int expireAfterWriteMinutes;


    /**
     * 创建基于Caffeine的Cache Manager
     *
     * @return CacheManager
     */
    @Bean
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        List<CaffeineCache> caches = Lists.newArrayList();
        Map<String, Cache<Object, Object>> map = getCacheType();
        for (String name : map.keySet()) {
            caches.add(new CaffeineCache(name, map.get(name)));
        }
        cacheManager.setCaches(caches);
        return cacheManager;
    }

    /**
     * 初始化自定义缓存策略
     *
     * @return Map
     */
    private static Map<String, Cache<Object, Object>> getCacheType() {
        Map<String, Cache<Object, Object>> map = new ConcurrentHashMap<>();
        map.put("name1", Caffeine.newBuilder().recordStats()
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .maximumSize(100)
                .build());
        map.put("name2", Caffeine.newBuilder().recordStats()
                .expireAfterWrite(50, TimeUnit.SECONDS)
                .maximumSize(50)
                .build());

        return map;
    }


}
